﻿using Hicap.QRCodeWarehouse.Processor.Const;
using MongoDB.Bson;
using MongoDB.Driver;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Hicap.QRCodeWarehouse.Processor.Manager
{
    /// <summary>
    /// Manager base
    /// </summary>
    /// <typeparam name="T">class</typeparam>
    public abstract class ManagerBase : IManagerBase
    {
        protected readonly IMongoClient MongoClient;

        protected ManagerBase(IMongoClient mongoClient)
        {
            MongoClient = mongoClient;
        }

        /// <summary>
        ///  Create or get collection
        /// </summary>
        /// <param name="collectionName">string</param>
        /// <param name="indexNameList">IList&lt;Tuple&lt;string, CreateIndexOptions&gt;&gt;</param>
        /// <returns>IMongoCollection&lt;T&gt;</returns>
        /// <remarks>when index notexist, create it</remarks>
        public virtual IMongoCollection<T> GetCollection<T>(string collectionName, IList<Tuple<string, CreateIndexOptions>> indexNameList = null)
        {
            //admin database
            IMongoDatabase database = MongoClient.GetDatabase(SysConst.DatabaseName);

            //get collection from collection name
            IMongoCollection<T> colllection = database.GetCollection<T>(collectionName);

            //have collection
            if (database.ListCollectionNames().ToEnumerable().All(x => x != collectionName))
            {
                //create collection
                database.CreateCollection(collectionName);
                colllection = database.GetCollection<T>(collectionName);
            }

            //create index when index not exist
            if (indexNameList != null)
            {
                foreach (Tuple<string, CreateIndexOptions> s in indexNameList)
                {
                    //have index
                    bool haveIndex = colllection.Indexes.List().ToList()
                        .Any(x => x.Values.Any(y => y.Equals(BsonValue.Create(s.Item2.Name))));

                    if (!haveIndex)
                    {
                        //create index
                        IndexKeysDefinition<T> key = Builders<T>.IndexKeys.Ascending(s.Item1);
                        colllection.Indexes.CreateOne(new CreateIndexModel<T>(key, s.Item2));
                    }
                }
            }

            Log.Information($"GetCollection : {colllection.CollectionNamespace.CollectionName}");
            return colllection;
        }
    }
}